package com.wyh.domain.vo.gfive.treeVo.tree_util;

//import com.wyh.domain.vo.threemeterTree.*;

import com.wyh.domain.vo.gfive.treeVo.*;
//import com.wyh.domain.vo.treeVo.*;

import java.util.*;

public class DepartmentTree {

//    只生成含有组织的树
    public static List<TreeNode> buildUserDepartmentTree(int userId, int userOrgId, List<OrganizationVO> aList){
        Map<Integer, TreeNode> aNodeMap = new HashMap<>();
        int unique_id = 0;

        // Create MasterDataTreeNode for each MasterDataOrganizationVO and map it
        for (OrganizationVO a : aList) {
            unique_id++;
            TreeNode node = new TreeNode(unique_id, a.getId(), a.getName(), "masterDataOrganization",a.getState());
            aNodeMap.put(a.getId(), node);
        }

        // Link MasterDataOrganizationVO nodes to their parents
        for (OrganizationVO a : aList) {
            if (a.getSuperiorId() != 0) {
                TreeNode node = aNodeMap.get(a.getId());
                TreeNode parentNode = aNodeMap.get(a.getSuperiorId());
                parentNode.getChildren().add(node);
            }
        }
        // Find the user's masterDataOrganization node
        TreeNode userOrgNode = aNodeMap.get(userOrgId);
        if (userOrgNode == null) {
            return Collections.emptyList(); // OrganizationPO not found
        }

        // Find the root node of the user's masterDataOrganization
        TreeNode rootNode = findRootNode(userOrgNode, aNodeMap);

        // Prune the tree to include only the relevant nodes for the user
        TreeNode prunedTree = pruneTree(rootNode, userOrgNode);

        // Return the pruned tree starting from the root node
        return Collections.singletonList(prunedTree);
    }




    //    只生成含有组织与下属项目的树
    public static List<TreeNode> buildUserDepartmentTree(int userId, int userOrgId, List<OrganizationVO> aList,List<ProjectVO> bList){
        Map<Integer, TreeNode> aNodeMap = new HashMap<>();
        Map<Integer, TreeNode> bNodeMap = new HashMap<>();
        int unique_id = 0;

        // Create MasterDataTreeNode for each MasterDataOrganizationVO and map it
        for (OrganizationVO a : aList) {
            unique_id++;
            TreeNode node = new TreeNode(unique_id, a.getId(), a.getName(), "masterDataOrganization",a.getState());
            aNodeMap.put(a.getId(), node);
        }

        // Link MasterDataOrganizationVO nodes to their parents
        for (OrganizationVO a : aList) {
            if (a.getSuperiorId() != 0) {
                TreeNode node = aNodeMap.get(a.getId());
                TreeNode parentNode = aNodeMap.get(a.getSuperiorId());
                parentNode.getChildren().add(node);
            }
        }

        // Create MasterDataTreeNode for each MasterDataProjectVO_1 and map it
        for (ProjectVO b : bList) {
            TreeNode node;
            if (b.getType() == 1) {
                unique_id++;
                node = new TreeNode(unique_id, b.getId(), b.getName(), "houses",b.getState());
            } else {
                unique_id++;
                node = new TreeNode(unique_id, b.getId(), b.getName(), "gardenArea",b.getState());
            }

            bNodeMap.put(b.getId(), node);
            if ("Y".equals(b.getIsConnected())) {
                TreeNode parentNode = aNodeMap.get(b.getSuperiorId());
                parentNode.getChildren().add(node);
            }
        }

        // Link MasterDataProjectVO_1 nodes to their parents in MasterDataProjectVO_1
        for (ProjectVO b : bList) {
            if ("N".equals(b.getIsConnected())) {
                TreeNode node = bNodeMap.get(b.getId());
                TreeNode parentNode = bNodeMap.get(b.getSuperiorId());
                parentNode.getChildren().add(node);
            }
        }

        // Find the user's masterDataOrganization node
        TreeNode userOrgNode = aNodeMap.get(userOrgId);
        if (userOrgNode == null) {
            return Collections.emptyList(); // OrganizationPO not found
        }

        // Find the root node of the user's masterDataOrganization
        TreeNode rootNode = findRootNode(userOrgNode, aNodeMap);

        // Prune the tree to include only the relevant nodes for the user
        TreeNode prunedTree = pruneTree(rootNode, userOrgNode);

        // Return the pruned tree starting from the root node
        return Collections.singletonList(prunedTree);
    }







//    完整的树
//    List<MasterDataTreeNode>
    public static List<TreeNode> buildUserDepartmentTree(int userId, int userOrgId, List<OrganizationVO> aList, List<ProjectVO> bList,
                                                         List<BuildingUnitsVO> cList, List<LayerVO> dList,
                                                         List<RoomVO> eList) {
        Map<Integer, TreeNode> aNodeMap = new HashMap<>();
        Map<Integer, TreeNode> bNodeMap = new HashMap<>();
        Map<Integer, TreeNode> cNodeMap = new HashMap<>();
        Map<Integer, TreeNode> dNodeMap = new HashMap<>();
        Map<Integer, TreeNode> eNodeMap = new HashMap<>();
        int unique_id = 0;

        // Create MasterDataTreeNode for each MasterDataOrganizationVO and map it
        for (OrganizationVO a : aList) {
            unique_id++;
            TreeNode node = new TreeNode(unique_id, a.getId(), a.getName(), "organization",a.getState());
            aNodeMap.put(a.getId(), node);
        }

        // Link MasterDataOrganizationVO nodes to their parents
        for (OrganizationVO a : aList) {
            if (a.getSuperiorId() != 0) {
                TreeNode node = aNodeMap.get(a.getId());
                TreeNode parentNode = aNodeMap.get(a.getSuperiorId());
                if (parentNode!=null){
//                    设置上一级的id，方便回溯遍历
                    node.setParentUniqueId(parentNode.getUnique_id());
                    parentNode.getChildren().add(node);
                }
            }
        }

        // Create MasterDataTreeNode for each MasterDataProjectVO_1 and map it
        for (ProjectVO b : bList) {

            TreeNode node;
            if (b.getType() == 1) {
                unique_id++;
                node = new TreeNode(unique_id, b.getId(), b.getName(), "houses",b.getState());
            } else {
                unique_id++;
                node = new TreeNode(unique_id, b.getId(), b.getName(), "gardenArea",b.getState());
            }

            bNodeMap.put(b.getId(), node);
            if ("Y".equals(b.getIsConnected())) {
                TreeNode parentNode = aNodeMap.get(b.getSuperiorId());
                if (parentNode!=null){
                    node.setParentUniqueId(parentNode.getUnique_id());
                    parentNode.getChildren().add(node);
                }
            }
        }

        // Link MasterDataProjectVO_1 nodes to their parents in MasterDataProjectVO_1
        for (ProjectVO b : bList) {
            if ("N".equals(b.getIsConnected())) {
                TreeNode node = bNodeMap.get(b.getId());
                TreeNode parentNode = bNodeMap.get(b.getSuperiorId());
                if (parentNode!=null){
                    node.setParentUniqueId(parentNode.getUnique_id());
                    parentNode.getChildren().add(node);
                }
            }
        }

        // Create MasterDataTreeNode for each MasterDataBuildingUnitsVO and map it
        for (BuildingUnitsVO c : cList) {
            TreeNode node;
            if (c.getType() == 0) {
                // Cluster
                unique_id++;
                node = new TreeNode(unique_id, c.getId(), c.getName(), "cluster", c.getState());
            } else if (c.getType() == 1) {
                // Building
                unique_id++;
                node = new TreeNode(unique_id, c.getId(), c.getName(), "building",c.getState());
            } else {
                // Unit
                unique_id++;
                node = new TreeNode(unique_id, c.getId(), c.getName(), "unit",c.getState());
            }
            cNodeMap.put(c.getId(), node);
            if ("Y".equals(c.getIsConnected())) {
                TreeNode parentNode = bNodeMap.get(c.getParentId());
                if (parentNode!=null){
                    node.setParentUniqueId(parentNode.getUnique_id());
                    parentNode.getChildren().add(node);
                }
            }
        }

        // Link MasterDataBuildingUnitsVO nodes to their parents in MasterDataBuildingUnitsVO
        for (BuildingUnitsVO c : cList) {
            if ("N".equals(c.getIsConnected())) {
                TreeNode node = cNodeMap.get(c.getId());
                TreeNode parentNode = cNodeMap.get(c.getParentId());
                if (parentNode!=null){
                    node.setParentUniqueId(parentNode.getUnique_id());
                    parentNode.getChildren().add(node);
                }
            }
        }

        // Create MasterDataTreeNode for each MasterDataLayerVO_1 and map it
        for (LayerVO d : dList) {
            unique_id++;
            TreeNode node = new TreeNode(unique_id, d.getId(), d.getName(), "layer",d.getState());
            dNodeMap.put(d.getId(), node);
            TreeNode parentNode = cNodeMap.get(d.getParentId());
            if (parentNode!=null){
                node.setParentUniqueId(parentNode.getUnique_id());
                parentNode.getChildren().add(node);
            }
        }

        // Create MasterDataTreeNode for each MasterDataRoomVO and map it
        for (RoomVO e : eList) {
            if (e.getState() == 1 || e.getState() == 2 || e.getState()==0) { // Check if the state is 1 or 2
                TreeNode node;
                if (e.getType() == 0) {
                    unique_id++;
                    node = new TreeNode(unique_id, e.getId(), e.getName(), "room",1);
                } else {
                    unique_id++;
                    node = new TreeNode(unique_id, e.getId(), e.getName(), "parkingSpot",1);
                }
                eNodeMap.put(e.getId(), node);
                TreeNode parentNode = dNodeMap.get(e.getBuildingId());
                if (parentNode!=null){
                    node.setParentUniqueId(parentNode.getUnique_id());
                    parentNode.getChildren().add(node);
                }
            }
        }

        // Find the user's masterDataOrganization node
        TreeNode userOrgNode = aNodeMap.get(userOrgId);
        if (userOrgNode == null) {
            return Collections.emptyList(); // OrganizationPO not found
        }

        // Find the root node of the user's masterDataOrganization
        TreeNode rootNode = findRootNode(userOrgNode, aNodeMap);

        // Prune the tree to include only the relevant nodes for the user
        TreeNode prunedTree = pruneTree(rootNode, userOrgNode);

        // Return the pruned tree starting from the root node
        return Collections.singletonList(prunedTree);
//        return prunedTree;
    }

    private static TreeNode findRootNode(TreeNode node, Map<Integer, TreeNode> nodeMap) {
        while (node.getParentUniqueId() != -1) {
            node = nodeMap.get(node.getParentUniqueId());
        }
        return node;
    }

    private static TreeNode pruneTree(TreeNode rootNode, TreeNode userOrgNode) {
        if (rootNode == userOrgNode) {
            return rootNode;
        }

        TreeNode prunedNode = new TreeNode(rootNode.getUnique_id(), rootNode.getId(), rootNode.getName(), rootNode.getType(),rootNode.getState());
        for (TreeNode child : rootNode.getChildren()) {
            TreeNode prunedChild = pruneTree(child, userOrgNode);
            if (prunedChild != null) {
                prunedNode.getChildren().add(prunedChild);
            }
        }
        return prunedNode.getChildren().isEmpty() ? null : prunedNode;
    }

    public static TreeNode removeDisabledNodes(TreeNode node) {
        if (node == null) {
            return null;
        }
        if (node.getState()==0&&!("roomparkingSpot").contains(node.getType())) {
            return null; // 如果当前节点已禁用，直接返回 null
        }
        List<TreeNode> prunedChildren = new ArrayList<>();
        for (TreeNode child : node.getChildren()) {
            TreeNode prunedChild = removeDisabledNodes(child);
            if (prunedChild != null) {
                prunedChildren.add(prunedChild);
            }
        }
        node.setChildren(prunedChildren);
        return node;
    }

    public static String getPathFromNode(TreeNode node, Map<Integer, TreeNode> nodeMap) {
        List<String> path = new ArrayList<>();
        while (node != null) {
            path.add(0, node.getName());
            if (node.getParentUniqueId() == -1) {
                break;
            }
            node = nodeMap.get(node.getParentUniqueId());
        }
        return String.join("/", path);
    }



    // 根据节点id与节点type查找并返回其子树
    public static TreeNode getSubTree(int housesId, String type, List<TreeNode> tree) {
        TreeNode nodeResult = findNodeByIdAndType(tree.get(0), housesId, type);
            return nodeResult;
//        for (MasterDataTreeNode node : tree) {
//            MasterDataTreeNode result = findNodeByIdAndType(node, housesId, type);
//            if (result != null) {
//                return result;
//            }
//        }
//        return null;
    }

    // 递归查找匹配的节点
    private static TreeNode findNodeByIdAndType(TreeNode node, int id, String type){
        if (node.getId()==id&&node.getType().equals(type)){
            return node;
        }
        for (TreeNode treeNode:node.getChildren()
             ) {
            TreeNode node2 = findNodeByIdAndType(treeNode, id, type);
            if (node2!=null){
                return node2;
            }
        }
        return null;
    }
}

